#将指定的列进行one_hot编码
def OneHotEncoder_packed(data,change_culomn_list,drop_org = False,file_name = 'OneHotTransform.txt'):
    '''
    传入DataFrame数据和要编码的列，return编码后的数据和编码转换的字典
    转换后的被转换的column中所有的NaN会被替换成为string：'NaN'
    '''
    import time
    import sys
    from sklearn.preprocessing import OneHotEncoder

    start = time.time()
    change_dict={}#建立转换字典，记录转换的内容

    for culomn in change_culomn_list:#对数据进行转换
        data[culomn] = data[culomn].fillna('NaN')  # 将NaN替换成str（用OneHotEncoder不能有NaN值）
        enc=OneHotEncoder()#实例化方法
        # OneHotEncoder只能fit array结构数据，dataframe结构需dropna().values后才能使用
        # 由于.value后就变成一行了，所以需要再.reshape（-1,1）转置变成列后再fit，不然就会当成只有一个样本
        enc.fit(data[culomn].values.reshape(-1,1))
        OneHotEncod = enc.transform(data[culomn].values.reshape(-1,1)).toarray()#将数据进行转换，生成array结构数据,不加toarray出来的看不明白是什么
        OneHot_frame = pd.DataFrame(OneHotEncod)#将array结构转换成DataFrame结构

        feature_dict = {}#构建用于替换列名的字典
        feature_name_list = list(enc.categories_[0])#enc.categories_可以得到转换的特征名称，是一个array结构,需要转换
        for index in range(len(feature_name_list)):#构建用于替换列名的字典
            print(feature_name_list[index])
            feature_name = culomn + '_'+ str(feature_name_list[index])
            feature_dict[index] = feature_name
        OneHot_frame.rename(columns=feature_dict, inplace=True)#将列名从数字替换成feature的名称
        # OneHot转换后的数据格式是float，占空间较大，所以将所有的列强制转换成int8
        OneHot_frame[list(feature_dict.values())] = OneHot_frame[list(feature_dict.values())].astype('int8')

        OneHot_frame.index = data.index#由于OneHot_frame的索引是重新编码的，所以需要将转换前数据的索引复制过来，便于拼接
        data = pd.concat([data, OneHot_frame], axis=1,)#将OneHot_frame拼接到原数据的后面
        change_dict[culomn] = list(feature_dict.values())#记录转换的内容
        print(OneHot_frame)
        print(data)

    if drop_org == True:
        data.drop(change_culomn_list, axis=1, inplace=True)#删除原有的列
    end = time.time()

    output = sys.stdout  # 保存原始的指向控制台
    #sys.stdout = clean.Logger(file_name)  # 将print的路径同时指向文件和控制台
    print('共用OneHotEncoder转换{}个特征，用时{:.3f}秒\n分别为：{}'.format(len(change_culomn_list),end-start,change_culomn_list))
    print('_'*30)
    for feature in change_culomn_list:
        print('{}列被转换为；'.format(feature))
        print(change_dict[feature])
        print('_' * 30)
    sys.stdout = output  # 将print的路径切换回控制台

    return data
